package com.example.miaosha.service.impl;

import com.alibaba.druid.util.StringUtils;
import com.example.miaosha.entity.UserInfo;
import com.example.miaosha.entity.UserPassword;
import com.example.miaosha.error.BusinessException;
import com.example.miaosha.error.EmBusinessError;
import com.example.miaosha.mapper.UserInfoMapper;
import com.example.miaosha.mapper.UserPasswordMapper;
import com.example.miaosha.service.UserService;
import com.example.miaosha.service.model.UserModel;
import com.example.miaosha.validator.ValidationResult;
import com.example.miaosha.validator.ValidatorImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.TimeUnit;

/**
 * @ClassName : UserServiceImpl
 * @CreateTime : 2020/09/22 16
 * @Author : lerry_li
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserInfoMapper userInfoMapper;
    @Autowired
    private UserPasswordMapper userPasswordMapper;

    @Autowired
    private ValidatorImpl validator;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public UserModel getUserById(Integer id) {
        UserInfo userInfo = userInfoMapper.selectByPrimaryId(id);
        if (userInfo == null) return null;
        UserPassword userPassword = userPasswordMapper.selectByUserId(id);
        return convertFromEntity(userInfo, userPassword);
    }

    @Override
    public UserModel getUserByIdInCache(Integer id) {
        //先到缓存中查用户对象，没有再去数据库中查
        UserModel userModel = (UserModel) redisTemplate.opsForValue().get("user_validate_" + id);
        if (userModel == null) {
            userModel = this.getUserById(id);
            redisTemplate.opsForValue().set("user_validate_" + id, userModel);
            redisTemplate.expire("user_validate_" + id, 10, TimeUnit.MINUTES);
        }
        return userModel;
    }

    @Override
    @Transactional
    public void register(UserModel userModel) throws BusinessException {
        if (userModel == null) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR);
        }
//        if (StringUtils.isEmpty(userModel.getName())
//                || userModel.getGender() == null
//                || userModel.getAge() == null
//                || StringUtils.isEmpty(userModel.getPhone())) {
//            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR);
//        }

        ValidationResult result = validator.validate(userModel);
        if (result.isHasError()) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, result.getErrMsg());
        }

        //实现model->dataObject方法
        UserInfo userInfo = convertFromModel(userModel);
        try {
            userInfoMapper.insertSelective(userInfo);
        } catch (DuplicateKeyException ex) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "手机号已经注册！");
        }

        userModel.setId(userInfo.getId());
        UserPassword userPassword = convertPasswordFromModel(userModel);
        userPasswordMapper.insertSelective(userPassword);

        return;

    }

    @Override
    public UserModel validateLogin(String phone, String encryptPassword) throws BusinessException {
        //通过用户手机号获取用户信息
        UserInfo userInfo = null;
        try {
            userInfo = userInfoMapper.selectByPhone(phone);
        } catch (Exception ex) {
            throw new BusinessException(EmBusinessError.SQL_ERROR);
        }
        if (userInfo == null) {
            throw new BusinessException(EmBusinessError.USER_LOGIN_FAIL);
        }
        UserPassword userPassword = userPasswordMapper.selectByUserId(userInfo.getId());
        UserModel userModel = convertFromEntity(userInfo, userPassword);

        //比较用户信息内加密的密码是否和传输进来的密码相匹配
        if (!StringUtils.equals(encryptPassword, userModel.getEncryptPassword())) {
            throw new BusinessException(EmBusinessError.USER_LOGIN_FAIL);
        }
        return userModel;
    }

    private UserPassword convertPasswordFromModel(UserModel userModel) {
        if (userModel == null) {
            return null;
        }
        UserPassword userPassword = new UserPassword();
        userPassword.setEncryptPassword(userModel.getEncryptPassword());
        userPassword.setUserId(userModel.getId());
        return userPassword;
    }

    private UserInfo convertFromModel(UserModel userModel) {
        if (userModel == null) {
            return null;
        }
        UserInfo userInfo = new UserInfo();
        BeanUtils.copyProperties(userModel, userInfo);

        return userInfo;
    }

    private UserModel convertFromEntity(UserInfo userInfo, UserPassword userPassword) {
        if (userInfo == null) return null;
        UserModel userModel = new UserModel();
        BeanUtils.copyProperties(userInfo, userModel);
        if (userPassword != null) userModel.setEncryptPassword(userPassword.getEncryptPassword());
        return userModel;
    }
}
